package com.gjzhao.fmmall.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.gjzhao.fmmall.constant.Constants;
import com.gjzhao.fmmall.entity.Users;
import com.gjzhao.fmmall.service.UserLoginService;
import com.gjzhao.fmmall.service.feign.UserCheckClient;
import com.gjzhao.fmmall.utils.JwtUtil;
import com.gjzhao.fmmall.utils.MD5Util;
import com.gjzhao.fmmall.vo.RespResultVO;
import io.jsonwebtoken.Claims;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

/**
 * @Description: 用户登录实现类
 * @Author: gjzhao
 * @Date Created in 2022-02-12 2:37 下午
 */
@Service
public class UserLoginServiceImpl implements UserLoginService {

    private Logger logger = LoggerFactory.getLogger(UserLoginServiceImpl.class);

    @Autowired
    private UserCheckClient userCheckClient; //报错是因为在服务降级类中实现了调用客户端，导致容器中存在了两个一样的名字，但是它们是存在在不同时期的
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public RespResultVO login(String username, String password) {

        //1.调用服务查询用户信息
        Users user = userCheckClient.checkUser(username);

        RespResultVO resultVO = null;
        //2.校验密码是否正确
        if (user == null) {
            resultVO = RespResultVO.failed("用户信息不存在");
        } else {
            //说明：由于使用了服务降级，返回用户信息为空可能是由服务调用失败引起的
            if (StrUtil.isEmpty(user.getUsername())) {
                resultVO = RespResultVO.failed("网络堵塞，user-check服务调用失败");
            } else {
                //对用户输入对密码进行MD5加密，然后与数据库的密码进行比对
                //TODO 可以考虑再进行一层加盐操作
                String md5Pwd = MD5Util.md5(password);
                if (md5Pwd.equals(user.getPassword())) {

                    //使用自己封装的Token工具类进行生成与解析
                    String token = jwtUtil.getToken(user.getUserId() + "", username, Constants.TOKEN_LOGIN_ROLE_ADMIN);
                    Claims claims = jwtUtil.parseToken(token);

                    logger.info("-----token中存放的信息:{}-------", String.valueOf(claims));

                    //以token为key，将当前用户登录信息放在redis中(不同登录用户会有不同的token值)，同时设置过期时间为30分钟
                    String userStr = JSONUtil.toJsonStr(user);
                    stringRedisTemplate.boundValueOps(token).set(userStr, 30, TimeUnit.MINUTES);

                    logger.info("-----存放token:{},到redis，存放的用户信息:{}-----", token, user.toString());

                    resultVO = RespResultVO.success("登录成功", user);
                } else {
                    resultVO = RespResultVO.failed("密码错误，登录失败");
                }
            }
        }
        return resultVO;
    }
}
